/*! Copyright(c) 2008-2012
 *
 *\file		Stm8s_uart3.c
 *\brief		
 *\details	
 *
 *\author	Cai Peifeng
 *\version	
 *\date		05Jun12
 *
 *\warning	
 *
 *\history \arg	05Jun12, Cai Peifeng, Create the file
 */

#include "Stm8s_uart3.h"
#include "Stm8s_clk.h"

/*!
 *\fn			void UART3_DeInit(void);
 *\brief   		Deinitializes the UART peripheral.
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_DeInit(void)
{
	UART3->BRR2 = UART3_BRR2_RESET_VALUE;
	UART3->BRR1 = UART3_BRR1_RESET_VALUE;

	UART3->CR1 = UART3_CR1_RESET_VALUE;
	UART3->CR2 = UART3_CR2_RESET_VALUE;
	UART3->CR3 = UART3_CR3_RESET_VALUE;
	UART3->CR4 = UART3_CR4_RESET_VALUE;
	UART3->CR6 = UART3_CR6_RESET_VALUE;
}

/*!
 *\fn			void UART3_Init(uint32_t BaudRate,UART3_WordLength_TypeDef WordLength,UART3_StopBits_TypeDef StopBits,UART3_Parity_TypeDef Parity, UART3_Mode_TypeDef Mode);
 *\brief   		Initializes the UART3 according to the specified parameters.
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_Init(uint32_t BaudRate,UART3_WordLength_TypeDef WordLength,UART3_StopBits_TypeDef StopBits,UART3_Parity_TypeDef Parity, UART3_Mode_TypeDef Mode)
{
	uint8_t BRR2_1 = 0,BRR2_2 = 0;
	uint32_t baudrate_mantissa = 0;
	uint32_t baudrate_mantissa100 = 0;

	assert_param(IS_UART3_WORDLENGTH_OK(WordLength));
	assert_param(IS_UART3_STOPBITS_OK(StopBits));
	assert_param(IS_UART3_PARITY_OK(Parity));
	assert_param(IS_UART3_BAUDRATE_OK(BaudRate));
	assert_param(IS_UART3_MODE_OK((uint8_t)Mode));

	UART3->CR1 &= (uint8_t)(~UART3_CR1_M);
	UART3->CR1 |= (uint8_t)WordLength;

	UART3->CR3 &= (uint8_t)(~UART3_CR3_STOP);
	UART3->CR3 |= (uint8_t)StopBits;

	UART3->CR1 &= (uint8_t)(~(UART3_CR1_PCEN | UART3_CR1_PS));
	UART3->CR1 |= (uint8_t)Parity;

	UART3->BRR1 &= (uint8_t)(~UART3_BRR1_DIVM);
	UART3->BRR2 &= (uint8_t)(~UART3_BRR2_DIVM);
	UART3->BRR2 &= (uint8_t)(~UART3_BRR2_DIVF);

	baudrate_mantissa = ((uint32_t)CLK_GetClockFreq() / (BaudRate << 4));
	baudrate_mantissa100 = ( ( ( uint32_t)CLK_GetClockFreq() * 100 ) / (BaudRate << 4));

	BRR2_1 = (uint8_t)( ( uint8_t)( ( ( baudrate_mantissa100 - (baudrate_mantissa * 100)) 
			<< 4 ) / 100) & (uint8_t)0x0F);

    BRR2_2 = (uint8_t)((baudrate_mantissa >> 4) & (uint8_t)0xF0);

	UART3->BRR2 = (uint8_t)(BRR2_1 | BRR2_2);
	UART3->BRR1 = (uint8_t)baudrate_mantissa;

	if( (uint8_t)( Mode & UART3_MODE_TX_ENABLE))
	{
		UART3->CR2 |= UART3_CR2_TEN;
	}
	else
	{
		UART3->CR2 &= (uint8_t)(~UART3_CR2_TEN);
	}

	if( (uint8_t)(Mode & UART3_MODE_RX_ENABLE))
	{
		UART3->CR2 |= UART3_CR2_REN;
	}
	else
	{
		UART3->CR2 &= (uint8_t)(~UART3_CR2_REN);
	}
		
}

/*!
 *\fn			void UART3_Cmd(FunctionalState NewState);
 *\brief   		Enable the UART3 peripheral.
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_Cmd(FunctionalState NewState)
{
	if( DISABLE != NewState)
	{
		UART3->CR1 &= (uint8_t)(~UART3_CR1_UARTD);
	}
	else
	{
		UART3->CR1 |= UART3_CR1_UARTD;
	}
}

/*!
 *\fn			void UART3_ITConfig(UART3_IT_TypeDef UART3_IT, FunctionalState NewState);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_ITConfig(UART3_IT_TypeDef UART3_IT, FunctionalState NewState)
{
	uint8_t uartreg = 0, itpos = 0x00;

	assert_param(IS_UART3_CONFIG_IT_OK(UART3_IT));
	assert_param(IS_FUNCTIONALSTATE_OK(NewState));

	uartreg = (uint8_t)((uint16_t) UART3_IT << 0x08);

	itpos = (uint8_t)((uint8_t) 1 << (uint8_t)((uint8_t)UART3_IT & (uint8_t)0x0F));

	if( DISABLE != NewState)
	{
		if( 0x01 == uartreg)
		{
			UART3->CR1 = itpos;
		}
		else if( 0x02 == uartreg)
		{
			UART3->CR2 |= itpos;
		}
		else if( 0x03 == uartreg)
		{
			UART3->CR4 |= itpos;
		}
		else
		{
			UART3->CR6 |= itpos;
		}
	}
	else
	{
		if( 0x1 == uartreg)
		{
			UART3->CR1 &= (uint8_t)(~itpos);
		}
		else if( 0x02 == uartreg)
		{
			UART3->CR2 &= (uint8_t)(~itpos);
		}
		else if( 0x03 == uartreg)
		{
			UART3->CR4 &= (uint8_t)(~itpos);
		}
		else
		{
			UART3->CR6 &= (uint8_t)(~itpos);
		}
	}
}

/*!
 *\fn			void UART3_LINBreakDetectionConfig(UART3_LINBreakDetectionLength_TypeDef UART3_LINBreakDetectionLength);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_LINBreakDetectionConfig(UART3_LINBreakDetectionLength_TypeDef UART3_LINBreakDetectionLength)
{
	return;
}

/*!
 *\fn			void UART3_LINConfig(UART3_LinMode_TypeDef UART3_Mode, UART3_LinAutosync_TypeDef UART3_Autosync,  UART3_LinDivUp_TypeDef UART3_DivUp);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_LINConfig(UART3_LinMode_TypeDef UART3_Mode, UART3_LinAutosync_TypeDef UART3_Autosync,  UART3_LinDivUp_TypeDef UART3_DivUp)
{
	return;
}

/*!
 *\fn			void UART3_LINCmd(FunctionalState NewState);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_LINCmd(FunctionalState NewState)
{
	return;
}

/*!
 *\fn			void UART3_ReceiverWakeUpCmd(FunctionalState NewState);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_ReceiverWakeUpCmd(FunctionalState NewState)
{
	return;
}

/*!
 *\fn			void UART3_WakeUpConfig( UART3_WakeUp_TypeDef UART3_WakeUp);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_WakeUpConfig( UART3_WakeUp_TypeDef UART3_WakeUp)
{
	
}

/*!
 *\fn			uint8_t UART3_ReceiveData8(void);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
uint8_t UART3_ReceiveData8(void)
{
	return ((uint8_t)UART3->DR);
}

/*!
 *\fn			uint16_t UART3_ReceiveData9(void);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
uint16_t UART3_ReceiveData9(void)
{
	uint16_t temp = 0;

	temp = (uint16_t)(((uint16_t)((uint16_t)UART3->CR1 & (uint16_t)UART3_CR1_R8)) << 1);
	 return (uint16_t)((((uint16_t)UART3->DR) | temp) & ((uint16_t)0x01FF));

}

/*!
 *\fn			void UART3_SendData8(uint8_t Data);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_SendData8(uint8_t Data)
{
	UART3->DR = Data;
}

/*!
 *\fn			void UART3_SendData9(uint16_t Data);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_SendData9(uint16_t Data)
{
    UART3->CR1 &= ((uint8_t)~UART3_CR1_T8);                  
    
    UART3->CR1 |= (uint8_t)(((uint8_t)(Data >> 2)) & UART3_CR1_T8); 
    
    UART3->DR   = (uint8_t)(Data); 	
}

/*!
 *\fn			void UART3_SendBreak(void);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_SendBreak(void)
{
    UART3->CR2 |= UART3_CR2_SBK;	
}

/*!
 *\fn			void UART3_SetAddress(uint8_t UART3_Address);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_SetAddress(uint8_t UART3_Address)
{
	assert_param( IS_UART3_ADDRESS_OK(UART3_Address));

	UART3->CR4 &= ((uint8_t)~UART3_CR4_ADD);
    UART3->CR4 |= UART3_Address;	
}

/*!
 *\fn			FlagStatus UART3_GetFlagStatus(UART3_Flag_TypeDef UART3_FLAG);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
FlagStatus UART3_GetFlagStatus(UART3_Flag_TypeDef UART3_FLAG)
{
    FlagStatus status = RESET;

    /* Check parameters */
    assert_param(IS_UART3_FLAG_OK(UART3_FLAG));

    /* Check the status of the specified UART3 flag*/
    if (UART3_FLAG == UART3_FLAG_LBDF)
    {
        if ((UART3->CR4 & (uint8_t)UART3_FLAG) != (uint8_t)0x00)
        {
            /* UART3_FLAG is set*/
            status = SET;
        }
        else
        {
            /* UART3_FLAG is reset*/
            status = RESET;
        }
    }
    else if (UART3_FLAG == UART3_FLAG_SBK)
    {
        if ((UART3->CR2 & (uint8_t)UART3_FLAG) != (uint8_t)0x00)
        {
            /* UART3_FLAG is set*/
            status = SET;
        }
        else
        {
            /* UART3_FLAG is reset*/
            status = RESET;
        }
    }
    else if ((UART3_FLAG == UART3_FLAG_LHDF) || (UART3_FLAG == UART3_FLAG_LSF))
    {
        if ((UART3->CR6 & (uint8_t)UART3_FLAG) != (uint8_t)0x00)
        {
            /* UART3_FLAG is set*/
            status = SET;
        }
        else
        {
            /* UART3_FLAG is reset*/
            status = RESET;
        }
    }
    else
    {
        if ((UART3->SR & (uint8_t)UART3_FLAG) != (uint8_t)0x00)
        {
            /* UART3_FLAG is set*/
            status = SET;
        }
        else
        {
            /* UART3_FLAG is reset*/
            status = RESET;
        }
    }

    /* Return the UART3_FLAG status*/
    return  status;		
}

/*!
 *\fn			void UART3_ClearFlag(UART3_Flag_TypeDef UART3_FLAG);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_ClearFlag(UART3_Flag_TypeDef UART3_FLAG)
{
    assert_param(IS_UART3_CLEAR_FLAG_OK(UART3_FLAG));

    /*Clear the Receive Register Not Empty flag */
    if (UART3_FLAG == UART3_FLAG_RXNE)
    {
        UART3->SR = (uint8_t)~(UART3_SR_RXNE);
    }
    /*Clear the LIN Break Detection flag */
    else if (UART3_FLAG == UART3_FLAG_LBDF)
    {
        UART3->CR4 &= (uint8_t)(~UART3_CR4_LBDF);
    }
    /*Clear the LIN Header Detection Flag */
    else if (UART3_FLAG == UART3_FLAG_LHDF)
    {
        UART3->CR6 &= (uint8_t)(~UART3_CR6_LHDF);
    }
    /*Clear the LIN Synch Field flag */
    else
    {
        UART3->CR6 &= (uint8_t)(~UART3_CR6_LSF);
    }	
}

/*!
 *\fn			ITStatus UART3_GetITStatus(UART3_IT_TypeDef UART3_IT);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
ITStatus UART3_GetITStatus(UART3_IT_TypeDef UART3_IT)
{
	ITStatus pendingbitstatus = RESET;

	uint8_t itpos = 0;
	uint8_t itmask1 = 0;
	uint8_t itmask2 = 0;
	uint8_t enablestatus  = 0;

	assert_param(IS_UART3_GET_IT_OK(UART3_IT));

	itpos = (uint8_t)((uint8_t)1 << ((uint8_t)UART3_IT & (uint8_t)0x0F));
	itmask1 = (uint8_t)((uint8_t)UART3_IT >> (uint8_t)4);
	itmask2 = (uint8_t)((uint8_t)1 << itmask1);

	if( UART3_IT_PE == UART3_IT)
	{
		enablestatus = (uint8_t)( (uint8_t)UART3->CR1 & itmask2);

		if( ( (UART3->SR & itpos) != ( uint8_t)0x00 ) && enablestatus)
		{
			pendingbitstatus = SET;
		}
		else
		{
			pendingbitstatus = RESET;
		}
	}
	else if( UART3_IT_LBDF == UART3_IT)
	{
		enablestatus = (uint8_t)( ( uint8_t)UART3->CR4 & itmask2);

		if( ( ( UART3->CR4 & itpos) != (uint8_t)0x00) && enablestatus)
		{
			pendingbitstatus = SET;
		}
		else
		{
			pendingbitstatus = RESET;
		}
	}
    else if (UART3_IT_LHDF == UART3_IT)
    {
        enablestatus = (uint8_t)((uint8_t)UART3->CR6 & itmask2);
        if (((UART3->CR6 & itpos) != (uint8_t)0x00) && enablestatus)
        {
            pendingbitstatus = SET;
        }
        else
        {
            pendingbitstatus = RESET;
        }
    }	
	else
	{
		enablestatus = (uint8_t)( (uint8_t)UART3->CR2 & itmask2);

		if( ( ( UART3->SR & itpos) != (uint8_t)0x00) && enablestatus)
		{
			pendingbitstatus = SET;
		}
		else
		{
			pendingbitstatus = RESET;
		}
	}
	
	return pendingbitstatus;	
}

/*!
 *\fn			void UART3_ClearITPendingBit(UART3_IT_TypeDef UART3_IT);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void UART3_ClearITPendingBit(UART3_IT_TypeDef UART3_IT)
{
	if( UART3_IT_RXNE == UART3_IT)
	{
		UART3->SR = (uint8_t)( ~UART3_SR_RXNE);
	}
	else
	{
		UART3->CR4 &= (uint8_t)( ~UART3_CR4_LBDF);
	}	
}

